﻿using System;
using Pfz.Extensions;

namespace Pfz.Serialization.BinaryBuiltIn
{
	/// <summary>
	/// Serializer for System.Type that only supports sending already registered types.
	/// </summary>
	public sealed class TypeByIdSerializer:
		IItemSerializer
	{
		/// <summary>
		/// Gets the singleton instance.
		/// </summary>
		public static readonly TypeByIdSerializer Instance = new TypeByIdSerializer();

		private TypeByIdSerializer()
		{
		}

		/// <summary>
		/// Serializes a type.
		/// </summary>
		public void Serialize(ConfigurableSerializerBase serializer, Type type)
		{
			var stream = serializer.Stream;

			var reference = serializer.GetItemSerializer(type);
			stream.WriteCompressedInt32(reference.Id);
		}

		/// <summary>
		/// Deserializes a type.
		/// </summary>
		public Type Deserialize(ConfigurableSerializerBase deserializer)
		{
			var stream = deserializer.Stream;
			int referenceId = stream.ReadCompressedInt32();

			return deserializer.GetTypeById(referenceId);
		}

		private static readonly Type _forType = typeof(TypeByIdSerializer).GetType();
		Type IItemSerializer.ForType
		{
			get
			{
				return _forType;
			}
		}

		void IItemSerializer.Serialize(ConfigurableSerializerBase serializer, object item)
		{
			Type type = (Type)item;
			Serialize(serializer, type);
		}
		object IItemSerializer.Deserialize(ConfigurableSerializerBase deserializer)
		{
			return Deserialize(deserializer);
		}
	}
}
